<template>
  <div class="chart-container" ref="chartRef"></div>
</template>

<script setup>
/**
 * 漏洞来源统计图表组件
 * @module VulnSourceChart
 * @description 用于展示不同来源的漏洞数量分布饼图
 */
import { ref, onMounted, watch, onUnmounted } from "vue";
import * as echarts from "echarts/core";
import { PieChart } from "echarts/charts";
import {
  TitleComponent,
  TooltipComponent,
  LegendComponent,
  GridComponent,
} from "echarts/components";
import { LabelLayout } from "echarts/features";
import { CanvasRenderer } from "echarts/renderers";
import { getVulnSourceCount } from "@/api/vulnerability";
// 注册必要的组件
echarts.use([
  PieChart,
  TitleComponent,
  TooltipComponent,
  LegendComponent,
  GridComponent,
  LabelLayout,
  CanvasRenderer,
]);

const props = defineProps({
  /**
   * 数据来源
   * 1-标准库
   */
  is_standard: {
    type: Number,
    default: 1,
  },
  /**
   * 图表标题
   */
  title: {
    type: String,
    default: "漏洞来源分布",
  },
  /**
   * 图表高度
   */
  height: {
    type: String,
    default: "300px",
  },
  /**
   * 文本颜色
   */
  textColor: {
    type: String,
    default: "#FFF",
  },
});
// 漏洞来源数据
const sourceData = ref([]);
async function fetchData(initFlag) {
  if (chartInstance) {
    // 判断是否为暗色主题
    const isDarkTheme = document.documentElement.classList.contains("dark");
    chartInstance.showLoading({
      text: "loading",
      color: isDarkTheme ? "#fff" : "#0073f3",
      textColor: isDarkTheme ? "#fff" : "#000",
      maskColor: isDarkTheme
        ? "rgba(0, 0, 0, 0.5)"
        : "rgba(230, 230, 230, 0.5)",
      zlevel: 0,
    });
  }
  const sourceRes = await getVulnSourceCount({
    is_standard: props.is_standard,
  });
  sourceData.value = sourceRes.data.map((item) => ({
    name: item.source,
    value: item.num_orders,
  }));
  if (chartInstance) {
    chartInstance.hideLoading();
  }
  if (initFlag) {
    initChart();
  } else {
    updateChart();
  }
}
// 图表DOM引用
const chartRef = ref(null);
// 图表实例
let chartInstance = null;

// 初始化图表
const initChart = () => {
  // 窗口大小变化时，重新调整图表大小
  window.addEventListener("resize", resizeChart);

  // 更新图表数据
  updateChart();
};

// 更新图表数据
const updateChart = () => {
  if (!chartInstance) return;

  // 判断是否为暗色主题
  const isDarkTheme = document.documentElement.classList.contains("dark");

  // 图表配置项
  const option = {
    backgroundColor: isDarkTheme ? "#192e4f" : "#fff",
    title: {
      text: props.title,
      left: "left",
      textStyle: {
        color: isDarkTheme ? "#DCDEE2" : "#333",
        fontSize: 14,
        fontWeight: 500,
        letterSpacing: 5,
      },
      top: 0,
    },
    tooltip: {
      trigger: "item",
      formatter: "{b}: {c} ({d}%)",
    },
    legend: {
      orient: "vertical",
      right: "5%",
      top: "center",
      itemGap: 15,
      data: sourceData.value.map((item) => item.name),
      textStyle: {
        color: isDarkTheme ? "#DCDEE2" : "#333",
      },
      itemWidth: 16,
      itemHeight: 16,
    },
    series: [
      // 添加外部大圆形背景
      {
        name: "",
        type: "pie",
        zlevel: -1,
        silent: true,
        radius: ["0%", "60%"],
        center: ["40%", "50%"],
        hoverAnimation: false,
        itemStyle: {
          color: isDarkTheme ? "#13223A" : "#E7ECF2",
        },
        label: {
          show: false,
        },
        data: [{ value: 1 }],
      },
      {
        name: "漏洞来源",
        type: "pie",
        radius: ["36%", "50%"],
        center: ["40%", "50%"],
        avoidLabelOverlap: false,
        itemStyle: {
          borderRadius: 0,
          borderColor: isDarkTheme ? "#1e2c46" : "#fff",
          borderWidth: 3,
        },
        label: {
          show: false,
        },
        emphasis: {
          label: {
            show: false,
          },
          itemStyle: {
            shadowBlur: 10,
            shadowOffsetX: 0,
            shadowColor: "rgba(0, 0, 0, 0.5)",
          },
        },
        labelLine: {
          show: false,
        },
        data: sourceData.value,
      },
      // 虚线圆圈饼图
      {
        name: "",
        type: "pie",
        zlevel: 2,
        silent: true,
        radius: ["30%", "30%"],
        center: ["40%", "50%"],
        hoverAnimation: false,
        itemStyle: {
          color: "transparent",
          borderColor: isDarkTheme
            ? "rgba(100, 144, 192, 0.3)"
            : "rgba(150, 160, 170, 0.5)",
          borderWidth: 2,
          borderType: "dotted",
        },
        label: {
          show: false,
        },
        data: [{ value: 1 }],
      },
      // 添加内部圆形背景
      {
        name: "",
        type: "pie",
        zlevel: 0,
        silent: true,
        radius: ["0", "30%"],
        center: ["40%", "50%"],
        hoverAnimation: false,
        itemStyle: {
          color: isDarkTheme ? "#1e2c46" : "#E7ECF2",
        },
        label: {
          show: false,
        },
        data: [{ value: 1 }],
      },
    ],
    // 添加明确的内部虚线圆圈
    graphic: Array.from({ length: 72 }).map((_, index) => {
      const angle = (index / 72) * Math.PI * 2;
      const x = 40 + Math.cos(angle) * 30; // 中心在40%，半径30%
      const y = 50 + Math.sin(angle) * 30; // 中心在50%

      return {
        type: "circle",
        shape: {
          cx: x + "%",
          cy: y + "%",
          r: index % 2 === 0 ? 1 : 0, // 隔点显示，形成虚线效果
        },
        style: {
          fill: isDarkTheme
            ? "rgba(100, 144, 192, 0.5)"
            : "rgba(150, 160, 170, 0.6)",
        },
        silent: true,
        z: 3,
      };
    }),
    color: [
      "#2468f2", // CNVD - 蓝色
      "#f59a23", // CVE - 橙色
      "#3ecbb2", // NVD - 青绿色
      "#f7cf4a", // 自定义 - 黄色
      "#4abaff", // 其他 - 浅蓝色
    ],
  };

  // 设置图表配置
  chartInstance.setOption(option);
};

// 调整图表大小
const resizeChart = () => {
  if (chartInstance) {
    chartInstance.resize();
    // 更新图表以刷新虚线
    updateChart();
  }
};

// 监听数据变化，更新图表
watch(
  () => props.is_standard,
  () => {
    fetchData();
  },
  { deep: true }
);
watch(
  () => props.textColor,
  () => {
    updateChart();
  }
);
watch(
  () => props.title,
  () => {
    updateChart();
  }
);

// 监听主题变化
const handleThemeChange = () => {
  if (chartInstance) {
    updateChart();
  }
};

// 组件挂载后初始化图表
onMounted(() => {
  if (!chartRef.value) return;

  // 初始化图表实例
  chartInstance = echarts.init(chartRef.value);
  fetchData(true);
  // 监听主题变化
  window.addEventListener("themechange", handleThemeChange);
});

// 组件卸载前销毁图表
onUnmounted(() => {
  if (chartInstance) {
    window.removeEventListener("resize", resizeChart);
    window.removeEventListener("themechange", handleThemeChange);
    chartInstance.dispose();
    chartInstance = null;
  }
});
</script>

<style lang="scss" scoped>
.chart-container {
  width: 100%;
  height: v-bind(height);
  border-radius: 8px;
}
</style>
